package com.supermap.dialogs;

import com.supermap.Helper;
import com.supermap.analyst.spatialstatistics.ClusteringDistributions;
import com.supermap.analyst.spatialstatistics.KMeansParameter;
import com.supermap.analyst.spatialstatistics.KMeasInitMethod;
import com.supermap.data.*;
import com.supermap.data.Enum;
import com.supermap.dialogs.advance.CJDialog;

import javax.swing.*;
import java.awt.*;

public class KMeansClusteringAnalystDialog extends CJDialog {
    private Workspace workspace;

    private JComboBox<String> srcDatasourceCmb;
    private JComboBox<String> srcDatasetCmb;
    private JTextField kClustersTxt;
    private JComboBox<KMeasInitMethod> kMeasInitMethodCmb;
    private JComboBox<String> retDatasourceCmb;
    private JTextField retDatasetTxt;

    private ProcessBarDialog processBarDialog;

    public KMeansClusteringAnalystDialog(Frame owner, String title, boolean modal, Workspace workspace) {
        super(owner, title, modal, 300, 300, new Object[]{workspace});
    }

    @Override
    protected void initializeArgs(Object[] args) {
        workspace = (Workspace) args[0];
    }

    @Override
    protected void initializeCore() {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new GridBagLayout());
        add(centerPanel, BorderLayout.CENTER);

        JPanel srcDataPanel = new JPanel();
        srcDataPanel.setBorder(BorderFactory.createTitledBorder("源数据"));
        srcDataPanel.setLayout(new GridBagLayout());
        centerPanel.add(srcDataPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel srcDatasourceLbl = new JLabel("数据源:");
        srcDataPanel.add(srcDatasourceLbl, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        srcDatasourceCmb = new JComboBox<>();
        Datasources datasources = workspace.getDatasources();
        int datasourcesCount = datasources.getCount();
        if (datasourcesCount > 0) {
            for (int i = 0; i < datasourcesCount; i++) {
                Datasource datasource = datasources.get(i);
                srcDatasourceCmb.addItem(datasource.getAlias());
            }
            srcDatasourceCmb.setSelectedIndex(0);
        }
        srcDatasourceCmb.addItemListener(e -> {
            String selectedDatasourceName = (String) e.getItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            loadDatasets(srcDatasetCmb, datasource);
        });
        srcDataPanel.add(srcDatasourceCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel srcDatasetLbl = new JLabel("数据集:");
        srcDataPanel.add(srcDatasetLbl, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        srcDatasetCmb = new JComboBox<>();
        if (datasourcesCount > 0) {
            String selectedDatasourceName = (String) srcDatasourceCmb.getSelectedItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            loadDatasets(srcDatasetCmb, datasource);
            srcDatasetCmb.setSelectedIndex(0);
        }
        srcDatasetCmb.setSelectedIndex(0);
        srcDataPanel.add(srcDatasetCmb, new GridBagConstraints(1, 1, 1, 1, 10, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JPanel kMeansParametersPanel = new JPanel();
        kMeansParametersPanel.setBorder(BorderFactory.createTitledBorder("参数设置"));
        kMeansParametersPanel.setLayout(new GridBagLayout());
        centerPanel.add(kMeansParametersPanel, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel kMeansInitMethodLbl = new JLabel("K均值聚类中心方法:");
        kMeansParametersPanel.add(kMeansInitMethodLbl, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        kMeasInitMethodCmb = new JComboBox<>();
        Enum[] enums = KMeasInitMethod.getEnums(KMeasInitMethod.class);
        for (Enum anEnum : enums) {
            kMeasInitMethodCmb.addItem((KMeasInitMethod) anEnum);
        }
        kMeansParametersPanel.add(kMeasInitMethodCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel kClustersLbl = new JLabel("K均值聚类数目:");
        kMeansParametersPanel.add(kClustersLbl, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        kClustersTxt = new JTextField();
        kClustersTxt.setText("0");
        kMeansParametersPanel.add(kClustersTxt, new GridBagConstraints(1, 1, 1, 1, 10, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JPanel retDataPanel = new JPanel();
        retDataPanel.setBorder(BorderFactory.createTitledBorder("结果数据"));
        retDataPanel.setLayout(new GridBagLayout());
        centerPanel.add(retDataPanel, new GridBagConstraints(0, 2, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel retDatasourceLbl = new JLabel("数据源:");
        retDataPanel.add(retDatasourceLbl, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        retDatasourceCmb = new JComboBox<>();
        if (datasourcesCount > 0) {
            for (int i = 0; i < datasourcesCount; i++) {
                Datasource datasource = datasources.get(i);
                retDatasourceCmb.addItem(datasource.getAlias());
            }
            retDatasourceCmb.setSelectedIndex(0);
        }
        retDatasourceCmb.addItemListener(e -> {
            String selectedDatasourceName = (String) e.getItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            String retDatasetName = datasource.getDatasets().getAvailableDatasetName("KMeansClusteringResult");
            retDatasetTxt.setText(retDatasetName);
        });
        retDataPanel.add(retDatasourceCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel retDatasetLbl = new JLabel("数据集:");
        retDataPanel.add(retDatasetLbl, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        retDatasetTxt = new JTextField();
        if (datasourcesCount > 0) {
            String selectedDatasourceName = (String) retDatasourceCmb.getSelectedItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            String retDatasetName = datasource.getDatasets().getAvailableDatasetName("KMeansClusteringResult");
            retDatasetTxt.setText(retDatasetName);
        }
        retDataPanel.add(retDatasetTxt, new GridBagConstraints(1, 1, 1, 1, 10, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));
    }

    @Override
    protected void doConfirmCore() {
        if (processBarDialog == null) {
            processBarDialog = new ProcessBarDialog((Frame) getOwner(), "K均值聚类分析", true);
            processBarDialog.setValue(0);
        }

        Datasource srcDatasource = workspace.getDatasources().get((String) srcDatasourceCmb.getSelectedItem());
        Dataset srcDataset = srcDatasource.getDatasets().get((String) srcDatasetCmb.getSelectedItem());
        DatasetVector srcDatasetVector = (DatasetVector) srcDataset;

        Datasource retDatasource = workspace.getDatasources().get((String) retDatasourceCmb.getSelectedItem());

        KMeansParameter kMeansParameter = new KMeansParameter();
        kMeansParameter.setKClusters(Integer.parseInt(kClustersTxt.getText()));
        kMeansParameter.setKMeasInitMethod((KMeasInitMethod) kMeasInitMethodCmb.getSelectedItem());

        new Thread(() -> {
            ClusteringDistributions.kmeans(srcDatasetVector, retDatasource, retDatasetTxt.getText(), kMeansParameter, steppedEvent -> {
                int percent = steppedEvent.getPercent();
                processBarDialog.setValue(percent);
                if (percent == 100) {
                    processBarDialog.setVisible(false);
                    processBarDialog.dispose();
                    processBarDialog = null;
                }
            });
        }).start();

        processBarDialog.setVisible(true);
        setVisible(false);
    }

    private void loadDatasets(JComboBox<String> srcDatasetCmb, Datasource datasource) {
        srcDatasetCmb.removeAll();
        Datasets datasets = datasource.getDatasets();
        int datasetCount = datasets.getCount();
        for (int i = 0; i < datasetCount; i++) {
            Dataset dataset = datasets.get(i);
            DatasetType datasetType = dataset.getType();
            if (datasetType == DatasetType.POINT) {
                srcDatasetCmb.addItem(dataset.getName());
            }
        }
    }
}
